package dynamicProgramming;

/**
 * 746. 使用最小花费爬楼梯
 * <p>
 * 给你一个整数数组 cost ，其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用，即可选择向上爬一个或者两个台阶。
 * <p>
 * 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。
 * <p>
 * 请你计算并返回达到楼梯顶部的最低花费。
 */
public class N746_MinCostClimbingStairs {
    // dp数组优化
    public int minCostClimbingStairs_(int[] cost) {
        int pre_2 = cost[0];    // 前两个台阶
        int pre_1 = cost[1];    // 前一个台阶
        int cur = 0;
        for (int i = 2; i < cost.length; ++i) {
            cur = Math.min(pre_2, pre_1) + cost[i];
            pre_2 = pre_1;
            pre_1 = cur;
        }
        return Math.min(pre_2, pre_1);
    }

    // 动态规划
    public int minCostClimbingStairs(int[] cost) {
        int[] dp = new int[cost.length];
        dp[0] = cost[0];    // 第一个台阶花费
        dp[1] = cost[1];    // 第二个台阶花费
        // 第三个台阶，可以是第一个台阶走两格，也可以是第二个台阶走一个，
        // 所以走的个数是前两个台阶花费中小的，加上本的花费（因为不是移动到第三个就好了，是要继续走出数组才算结束）
        for (int i = 2; i < dp.length; ++i)
            dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];
        return Math.min(dp[dp.length - 1], dp[dp.length - 2]);  // 计算到最后两格台阶花费，看哪个少返回哪个
    }

    public static void main(String[] args) {
        N746_MinCostClimbingStairs solution = new N746_MinCostClimbingStairs();
        int[] cost = {10, 15, 20};
        System.out.println(solution.minCostClimbingStairs_(cost));
    }
}
